package com.slwu.controller;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.slwu.common.RESP;
import com.slwu.entity.Plot;
import com.slwu.request.plot.PlotAddParam;
import com.slwu.request.plot.PlotEditParam;
import com.slwu.request.plot.PlotIdParam;
import com.slwu.request.plot.PlotPageParam;
import com.slwu.service.IPlotService;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import io.swagger.annotations.ApiOperation;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author wushaolin
 * @since 2025-10-29
 */
@RestController
@RequestMapping("/plot")
public class PlotController {

    @Resource
    private IPlotService plotService;

    @ApiOperationSupport(order = 1)
    @ApiOperation("获取地块分页")
    @GetMapping("/page")
    public RESP<Page<Plot>> page(PlotPageParam plotPageParam) {
        return RESP.ok(plotService.page(plotPageParam));
    }

    @ApiOperationSupport(order = 2)
    @ApiOperation("新增地块")
    @PostMapping("/add")
    public RESP<Boolean> add(@RequestBody @Validated PlotAddParam param) {
        Plot plot = new Plot();
        BeanUtil.copyProperties(param, plot);
        plot.setId(IdUtil.objectId());
        return RESP.ok(plotService.save(plot));
    }

    @ApiOperationSupport(order = 3)
    @ApiOperation("修改地块")
    @PostMapping("/edit")
    public RESP<Boolean> edit(@RequestBody @Validated PlotEditParam param) {
        // 1.使用主键更新时不能更新分片字段：village
        // where条件不指定分片字段会更新一遍所有表
//        Plot plot = new Plot();
//        plot.setId(param.getId());
//        plot.setName(param.getName());
//        return RESP.ok(plotService.updateById(plot));
        // 2.推荐使用以下写法，where条件指定分片字段锁定固定表进行更新
//        plotService.lambdaUpdate()
//                .set(Plot::getName, param.getName())
//                // 避免 PostgreSQL 将 Map 识别为 hstore，转为字符串写入
//                .set(ObjectUtil.isNotEmpty(param.getExt()), Plot::getExt, JSONUtil.toJsonStr(param.getExt()))
//                .eq(Id::getId, param.getId())
//                .eq(ObjectUtil.isNotEmpty(param.getVillage()), Plot::getVillage, param.getVillage())
//                .update();
//        return RESP.ok(true);
        // 3.当字段存在特殊类型，需要使用TypeHandler处理时避免使用lambdaUpdate
        Plot plot = BeanUtil.toBean(param, Plot.class);
        plot.setVillage(null);
        return RESP.ok(plotService.updateById(plot));
    }

    @ApiOperationSupport(order = 4)
    @ApiOperation("地块详情")
    @GetMapping("/detail")
    public RESP<Plot> detail(PlotIdParam param) {
        // 同更新操作，查询时可以where条件指定分片字段锁定固定表查询
//        return RESP.ok(plotService.getOne(param.getId()));
        QueryWrapper<Plot> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(Plot::getId, param.getId());
        queryWrapper.lambda().eq(ObjectUtil.isNotEmpty(param.getVillage()), Plot::getVillage, param.getVillage());
        return RESP.ok(plotService.getOne(queryWrapper));
    }

    @ApiOperationSupport(order = 5)
    @ApiOperation("删除地块")
    @PostMapping("/delete")
    public RESP<Boolean> delete(@RequestBody @Validated PlotIdParam param) {
        // 同更新操作，删除时可以where条件指定分片字段锁定固定表删除
//        return RESP.ok(plotService.removeById(param.getId()));
        QueryWrapper<Plot> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(Plot::getId, param.getId());
        queryWrapper.lambda().eq(ObjectUtil.isNotEmpty(param.getVillage()), Plot::getVillage, param.getVillage());
        return RESP.ok(plotService.remove(queryWrapper));
    }

}
